From 6ce270bd78b436c69051b95f1566957df90034ab Mon Sep 17 00:00:00 2001 From: Debian Qt/KDE Maintainers Date: Thu, 29 Jan 2026 22:25:23 +0300 Subject: [PATCH] QReadWriteLock: fix data race on the d_ptr members Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit?id=80d01c4ccb697b9d Last-Update: 2025-12-14 The loadRelaxed() at the beginning of tryLockForRead/tryLockForWrite isn't enough to bring us the non-atomic write of the recursive bool. Same issue with the std::mutex itself. Gbp-Pq: Name qreadwritelock_data_race.diff --- src/corelib/thread/qreadwritelock.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp index 9dd850311..84d73444b 100644 --- a/src/corelib/thread/qreadwritelock.cpp +++ b/src/corelib/thread/qreadwritelock.cpp @@ -258,7 +258,10 @@ bool QReadWriteLock::tryLockForRead(int timeout) d = val; } Q_ASSERT(!isUncontendedLocked(d)); - // d is an actual pointer; + // d is an actual pointer; acquire its contents + d = d_ptr.loadAcquire(); + if (!d || isUncontendedLocked(d)) + continue; if (d->recursive) return d->recursiveLockForRead(timeout); @@ -365,7 +368,10 @@ bool QReadWriteLock::tryLockForWrite(int timeout) d = val; } Q_ASSERT(!isUncontendedLocked(d)); - // d is an actual pointer; + // d is an actual pointer; acquire its contents + d = d_ptr.loadAcquire(); + if (!d || isUncontendedLocked(d)) + continue; if (d->recursive) return d->recursiveLockForWrite(timeout); -- 2.30.2